#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
Usage:
  1) reading text from stdin:
     "cat foo.py | dpaste -n Name -t 'content of foo.txt' -s Python"
"""

import sys
import socket
import optparse
import webbrowser
from urllib import urlopen, urlencode
from optparse import OptionParser

socket.setdefaulttimeout(5)

# list of available syntax highlights
syntaxes = ['Python', 'PythonConsole', 'Sql', 'DjangoTemplate', 'JScript',
            'Css', 'Xml', 'Diff', 'Ruby', 'Rhtml', 'Haskell', 'Apache', 'Bash']

# base url of dpaste
url = 'http://dpaste.com/'

def dpaste(content, poster='', title='', language='', hold=False):
    if language not in syntaxes and language != '':
        # the given language is not available
        # check if the casing was wrong and fix it
        language = language.lower()
        for syntax in syntaxes:
            if language == syntax.lower():
                language = syntax
                break
        else:
            # the casing wasn't wrong, the language is not available
            raise ValueError('The syntax highlight specified is not available.')

    # build up the dict with the POST data
    data = dict(content=content, poster=poster, title=title, language=language,
                hold='checked' if hold else '')
    try:
        # encode the data and send the request
        page = urlopen(url, urlencode(data))
    except IOError, err:
        # XXX: are other IOError except the timeout possible?
        sys.exit('Connection timeout')
    #print page.read()
    return page.geturl()

def delete_paste(pasteid):
    page = urlopen('/'.join([url, str(pasteid), 'delete', '']), urlencode({}))
    print page.read()

if __name__ == '__main__':
    # if the program is executed directly parse the command line options
    # and read the text to paste from stdin

    parser = optparse.OptionParser()
    parser.add_option('-n', '--name', dest='poster', default='',
                      metavar='NICK', help='your name (optional)')

    parser.add_option('-t', '--title', dest='title', default='',
                      metavar='TITLE', help='the title of the post (optional)')

    parser.add_option('-s', '--syntax', dest='language', default='',
                      metavar='SYNTAX', help=(
                        'the syntax highlight to use (default: plain). '
                        'Possible values: %s' % ', '.join(syntaxes)))

    parser.add_option('-H', '--hold', dest='hold', default=False,
                      action='store_true', help=('hold the paste for at least '
                      '30 days (default: %default)'))

    parser.add_option('-d', '--delete', dest='pasteid', default='',
                      help='Delete the paste with the given id.')

    parser.add_option('-o', '--open', dest='open', default=False,
                      action='store_true', help='open the page in the browser')

    options, args = parser.parse_args()

    if options.pasteid:
        delete_paste(options.pasteid)

    # if stdin is a tty the user can write/paste the code directly
    # so print a line with the instructions
    if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty():
        print 'Type the code and press Ctrl+D:'
    content = sys.stdin.read()

    # if the string is empty or contains only whitespaces don't paste anything
    if not content.strip():
        sys.exit('No code to paste.')

    #print '-'*150
    #print urlencode(data)
    #print '-'*150

    # max 3 args are allowed
    if len(args) > 3:
        sys.exit('Too many args.')

    # make sure that list of args has 3 values to avoid IndexErrors later
    args = list(args)
    while len(args) < 3:
        args.append('')

    # use either the options or the args
    poster = options.poster or args[0]
    title = options.title or args[1]
    language = options.language or args[2]
    hold = options.hold

    # paste the code and get back the url of the page
    url = dpaste(content, poster, title, language, hold)

    # print the url of the page and open it in the browser if the -o/--open
    # options is specified
    print url
    if options.open:
        webbrowser.open(url)
